home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / (A)TA / (A)TAX.ADF / dskmap / dm.c < prev    next >
C/C++ Source or Header  |  1986-10-08  |  9KB  |  344 lines

  1. /*  :ts=8 bk=0
  2.  * Disk mapper.  Uses trackdisk.device to grab and read sector bitmap
  3.  * to discover what's allocated, then displays a (hopefully) pretty picture
  4.  * showing disk useage.
  5.  *
  6.  * Crufted together by Leo Schwab while desperately bored.  8606.8
  7.  * Turned into something working for the Manx compiler.  8607.23
  8.  */
  9.  
  10. #include <exec/types.h>
  11. #include <exec/memory.h>
  12. #include <intuition/intuition.h>
  13. #include <libraries/dos.h>
  14. #include <devices/trackdisk.h>
  15.  
  16. #define    REV        0L
  17. #define BLOCKSIZE    TD_SECTOR
  18. #define NUMBLOCKS    (NUMCYLS * NUMHEADS * NUMSECS)
  19. #define ROOTBLOCK    (NUMBLOCKS / 2)
  20. #define BITMAPINDEX    79
  21. #define NUMLONGS    (NUMBLOCKS / 32)
  22. #define XX        6L
  23. #define    YY        6L
  24. #define XOFF        30L
  25. #define YOFF        25L
  26. #define BRKOVER        91L    /*  11 * YY + YOFF  */
  27. #define SEP        6
  28.  
  29. extern void    *OpenLibrary(), *OpenDevice(), *OpenWindow(), *AllocMem(),
  30.         *Lock(), *Info(), *CreatePort(), *CreateExtIO();
  31. extern long    TextLength();
  32.  
  33.  
  34. struct NewWindow windef = {
  35.     0, 0, 640, 180,
  36.     -1, -1,
  37.     CLOSEWINDOW,
  38.     WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE | SMART_REFRESH | ACTIVATE,
  39.     NULL, NULL,
  40.     (UBYTE *) "Disk Allocation Map ",
  41.     NULL, NULL, 0, 0, 0, 0,
  42.     WBENCHSCREEN
  43. };
  44.  
  45. struct IntuiText ok = {
  46.     AUTOFRONTPEN, AUTOBACKPEN,
  47.     AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE,
  48.     AUTOITEXTFONT,
  49.     (UBYTE *) "OK",
  50.     AUTONEXTTEXT
  51. };
  52.  
  53. struct IntuiText errmsg = {
  54.     AUTOFRONTPEN, AUTOBACKPEN,
  55.     AUTODRAWMODE, AUTOLEFTEDGE, AUTOTOPEDGE,
  56.     AUTOITEXTFONT,
  57.     NULL,    /*  Gets filled in later  */
  58.     AUTONEXTTEXT
  59. };
  60.  
  61. struct Window    *win;
  62. struct RastPort *rp;
  63. struct InfoData *id;
  64. struct IOExtTD    *diskreq;
  65. struct MsgPort    *diskport;
  66. ULONG        diskchangecount, lok, *diskbuffer;
  67. void        *IntuitionBase, *GfxBase;
  68.  
  69.  
  70. main (ac, av)
  71. char *av[];
  72. {
  73.     long k, x, y;
  74.     int unit, bmsect, free = NUMBLOCKS-2;
  75.     short i, n, l;
  76.     char buf[80];
  77.  
  78.     if (!ac) {    /*  Run from workbench (ick!)  */
  79.         /*  I'll make this part better someday.....  */
  80.         strcpy (buf, "df0:");
  81.     } else {    /*  Run from CLI (thank you)  */
  82.         if (ac == 1) {
  83.             printf ("Drive specifier: ");
  84.             gets (buf);
  85.         } else
  86.             strcpy (buf, av[1]);
  87.     }
  88.  
  89.     openstuff ();
  90.  
  91.     if (!(lok = Lock (buf, ACCESS_READ)))
  92.         die ("Can't obtain lock for specified device.");
  93.  
  94.     if (!(id = AllocMem ((long) sizeof (*id), MEMF_CLEAR)))
  95.         die ("Can't get InfoData memory.");
  96.  
  97.     if (!Info (lok, id))
  98.         die ("Call to Info() failed.");
  99.  
  100.     if (id -> id_DiskType == ID_NO_DISK_PRESENT)
  101.         die ("No disk in drive.");
  102.  
  103.     unit = id -> id_UnitNumber;
  104.     FreeMem (id, (long) sizeof (*id));  id = NULL;
  105.     opendisk (unit);
  106.     MotorOn ();
  107.     GetSector ((long) ROOTBLOCK);
  108.     bmsect = diskbuffer[BITMAPINDEX];
  109.     GetSector ((long) bmsect);
  110.     MotorOff ();
  111.  
  112.     /*
  113.      * At this point, we now have the bitmap in the disk buffer.
  114.      * This is what the first longword in the bitmap represents:
  115.      *
  116.      *    333322222222221111111111
  117.      *    32109876543210987654321098765432    Sector #
  118.      *    --------------------------------
  119.      *    10100101001010010010010001010011    Longword
  120.      *    MSB                 LSB
  121.      *
  122.      * If the bit is set, the sector is free.
  123.      *
  124.      * Sectors 0 and 1 contain the boot block.  Thus, the DOS is not
  125.      * allowed to walk on them, and they are permanently allocated.
  126.      * However, the bitmap does not reflect this i.e. the bitmap starts
  127.      * at sector 2, which is indicated by bit 0, longword 1.  This means
  128.      * we have to offset everything by two.  Can you say "crock?"
  129.      *
  130.      * Actually, I suppose this is good, since it prevents some would-be
  131.      * smart person from un-allocating those sectors and messing things
  132.      * up badly.
  133.      *
  134.      * Bitmap starts at longword 1; longword 0 appears to be some kind
  135.      * of significant garbage (checksum?)
  136.      *
  137.      * For more info on how I found the bitmap sector, consult the DOS
  138.      * Technical Reference Manual, p. 1-1 - 1-2
  139.      */
  140.  
  141.     SetAPen (rp, 3L);
  142.     RectFill (rp, XOFF, YOFF, XX+XOFF, YY+YY+YOFF);    /*  Show first two  */
  143.     for (i=1; i<=NUMLONGS; i++) {
  144.         k = diskbuffer[i];
  145.         for (n=0; n<32; n++)
  146.             /*  Bits progress from low to high order  */
  147.             if (i<NUMLONGS || n<30) {    /*  Ignore last two  */
  148.                 if (~k & 1) {
  149.                     /*  Perform icky conversion  */
  150.                     free--;
  151.                     l = (i-1 << 5) + n + 2;
  152.                     x = (l / 22) * XX + XOFF;
  153.                     y = (l % 22) * YY + YOFF;
  154.                     if (y >= BRKOVER)
  155.                         y += SEP;
  156.                     RectFill (rp, x, y, x+XX-1, y+YY-1);
  157.                 }
  158.                 k >>= 1;
  159.             }
  160.     }
  161.  
  162.     /*  Draw grid so we can see  */
  163.     SetAPen (rp, 1L);
  164.     for (x=XOFF; x<=80*XX+XOFF; x += XX) {
  165.         Move (rp, x, YOFF);
  166.         Draw (rp, x, YOFF+11*YY);
  167.         Move (rp, x, BRKOVER+SEP);
  168.         Draw (rp, x, BRKOVER+SEP+11*YY);
  169.     }
  170.     for (y=0; y<=11*YY; y += YY) {
  171.         Move (rp, XOFF, y+YOFF);
  172.         Draw (rp, XOFF+80*XX, y+YOFF);
  173.         Move (rp, XOFF, y+SEP+BRKOVER);
  174.         Draw (rp, XOFF+80*XX, y+SEP+BRKOVER);
  175.     }
  176.  
  177.     /*  Draw map markings  */
  178.     Move (rp, XOFF+XX/2, YOFF);      Draw (rp, XOFF+XX/2, YOFF-3);
  179.     Move (rp, XOFF+80*XX-XX/2, YOFF); Draw (rp, XOFF+80*XX-XX/2, YOFF-3);
  180.     Move (rp, XOFF, YOFF+YY/2);      Draw (rp, XOFF-3, YOFF+YY/2);
  181.     Move (rp, XOFF, YOFF+YY*10+YY/2); Draw (rp, XOFF-3, YOFF+YY*10+YY/2);
  182.     Move (rp, XOFF-1, YOFF-3);      Text (rp, "0", 1L);
  183.     Move (rp, XOFF+79*XX-1, YOFF-3);  Text (rp, "79", 2L);
  184.     Move (rp, XOFF-12, YOFF+6);      Text (rp, "0", 1L);
  185.     Move (rp, XOFF-20, YOFF+11*YY);   Text (rp, "10", 2L);
  186.  
  187.     /*  Do labels  */
  188.     sprintf (buf, "Bitmap on sector %d", bmsect);
  189.     Move (rp, XOFF, 176L);
  190.     Text (rp, buf, (long) strlen (buf));
  191.     sprintf (buf, "Sectors free: %d", free);
  192.     Move (rp, 250L, 176L);
  193.     Text (rp, buf, (long) strlen (buf));
  194.     sprintf (buf, "Allocated: %d", (int) NUMBLOCKS-free);
  195.     Move (rp, 450L, 176L);
  196.     Text (rp, buf, (long) strlen (buf));
  197.     Move (rp, 520L, 60L);
  198.     Text (rp, "Surface 0", 9L);
  199.     Move (rp, 520L, 132L);
  200.     Text (rp, "Surface 1", 9L);
  201.  
  202.     /*  Wait for close gadget  */
  203.     Wait (1L << win -> UserPort -> mp_SigBit);
  204.     closestuff ();
  205. }
  206.  
  207.  
  208. openstuff ()
  209. {
  210.     if (!(IntuitionBase = OpenLibrary ("intuition.library", REV))) {
  211.         /*
  212.          * If we can't open Intuition, then we can't use
  213.          * AutoRequest ()
  214.          */
  215.         printf ("Intuition failed; you'll have to use logic.\n");
  216.         closestuff ();
  217.         exit (100);
  218.     }
  219.  
  220.     if (!(GfxBase = OpenLibrary ("graphics.library", REV))) {
  221.         printf ("Art shop closed.\n");
  222.         closestuff ();
  223.         exit (100);
  224.     }
  225.  
  226.     if (!(win = OpenWindow (&windef))) {
  227.         printf ("Window painted shut.\n");
  228.         closestuff ();
  229.         exit (100);
  230.     }
  231.     rp = win -> RPort;
  232. }
  233.  
  234. opendisk (unit)
  235. int unit;
  236. {
  237.     long err;
  238.     char *buf[80];
  239.  
  240.     if (!(diskport = CreatePort (NULL, NULL)))
  241.         die ("No port.");
  242.  
  243.     if (!(diskreq = CreateExtIO (diskport, (long) sizeof (*diskreq))))
  244.         die ("Can't make IO block.");
  245.  
  246.     if (err = OpenDevice (TD_NAME, (long) unit, diskreq, NULL)) {
  247.         sprintf (buf, "Can't get at disk; err = %ld.", err);
  248.         DeleteExtIO (diskreq, (long) sizeof (*diskreq));
  249.         diskreq = NULL;
  250.         die (buf);
  251.     }
  252.  
  253.     if (!(diskbuffer = AllocMem (BLOCKSIZE, MEMF_CLEAR | MEMF_CHIP)))
  254.         die ("Can't allocate disk buffer.");
  255.  
  256.     diskreq -> iotd_Req.io_Command = TD_CHANGENUM;
  257.     DoIO (diskreq);
  258.     diskchangecount = diskreq -> iotd_Req.io_Actual;
  259. }
  260.  
  261. closestuff ()
  262. {
  263.     if (lok)
  264.         UnLock (lok);
  265.     if (diskreq) {
  266.         CloseDevice (diskreq);
  267.         DeleteExtIO (diskreq, (long) sizeof (*diskreq));
  268.     }
  269.  
  270.     if (diskbuffer)
  271.         FreeMem (diskbuffer, (long) BLOCKSIZE);
  272.     if (id)
  273.         FreeMem (id, (long) sizeof (*id));
  274.     if (diskport)
  275.         DeletePort (diskport);
  276.     if (win)
  277.         CloseWindow (win);
  278.     if (GfxBase)
  279.         CloseLibrary (GfxBase);
  280.     if (IntuitionBase)
  281.         CloseLibrary (IntuitionBase);
  282. }
  283.  
  284. die (str)
  285. UBYTE *str;
  286. {
  287.     errmsg.IText = str;
  288.     AutoRequest (win, &errmsg, NULL, &ok, NULL, NULL,
  289.              TextLength (rp, str, (long) strlen (str)) + 40, 46L);
  290.     closestuff ();
  291.     exit (100);
  292. }
  293.  
  294. /*
  295.  * The following routines were stolen from an RKM example by Bob Peck and
  296.  * hacked up a bit.
  297.  */
  298.  
  299. GetSector (sector)
  300. long sector;
  301. {
  302.     LONG offset = sector * BLOCKSIZE;
  303.  
  304.     diskreq -> iotd_Req.io_Length = BLOCKSIZE;      
  305.     diskreq -> iotd_Req.io_Data = (APTR) diskbuffer;    
  306.         /* show where to put the data when read */
  307.     diskreq -> iotd_Req.io_Command = ETD_READ;
  308.         /* check that disk not changed before reading */
  309.     diskreq -> iotd_Count = diskchangecount;
  310.     
  311.     /* convert from cylinder, head, sector to byte-offset value to get
  312.         * right one (as dos and everyone else sees it)...*/
  313.     
  314.     /* driver reads one CYLINDER at a time (head does not move for
  315.      * 22 sequential sector reads, or better-put, head doesnt move for
  316.      * 2 sequential full track reads.)
  317.      */
  318.     
  319.     diskreq -> iotd_Req.io_Offset = offset;
  320.     DoIO (diskreq);
  321.     return (0);
  322. }
  323.  
  324. MotorOn()
  325. {
  326.     /* TURN ON DISK MOTOR ... old motor state is returned in io_Actual */
  327.     diskreq -> iotd_Req.io_Length = 1;
  328.     /* this says motor is to be turned on */
  329.     diskreq -> iotd_Req.io_Command = TD_MOTOR;
  330.     /* do something with the motor */
  331.     DoIO (diskreq);
  332.     return (0);
  333. }
  334.  
  335. MotorOff()
  336. {
  337.     diskreq -> iotd_Req.io_Length = 0;    
  338.     /* says that motor is to be turned on */
  339.     diskreq -> iotd_Req.io_Command = TD_MOTOR;    
  340.     /* do something with the motor */
  341.     DoIO (diskreq);
  342.     return (0);
  343. }
  344.